package com.dayatang.hrm.compensation.domain;

import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert;

import com.dayatang.commons.domain.AbstractEntity;
import com.dayatang.commons.domain.InstanceFactory;
import com.dayatang.hrm.compensation.context.CompensationMessageSource;
import com.dayatang.hrm.compensation.domain.exception.CompensationRuntimeException;
import com.dayatang.hrm.organisation.domain.Organization;
import com.dayatang.hrm.staffing.domain.Employee;

/**
 * 会计年度
 * 
 * @author chencao
 * 
 */
@Entity
@Table(name = "pay_fiscal_year")
@NamedQueries( { @NamedQuery(name = "FiscalYear.findByOrganization", query = "select o from FiscalYear o inner join o.org org where org = :pOrg ") })
public class FiscalYear extends AbstractEntity {

	/**
	 * 
	 */
	private static final long serialVersionUID = 3023688429830510084L;

	private static FiscalYearRepository fiscalYearRepository;

	protected static MessageSourceAccessor messages = CompensationMessageSource
			.getAccessor();

	// 年度
	@Column(name = "fiscal_year", nullable = false)
	private Integer year;
	// 所属机构
	@ManyToOne
	@JoinColumn(name = "org_id", nullable = false)
	private Organization org;
	// 操作人
	@ManyToOne
	@JoinColumn(name = "operator_id")
	private Employee operator;

	public FiscalYear() {
	}

	public static FiscalYearRepository getFiscalYearRepository() {
		if (fiscalYearRepository == null) {
			fiscalYearRepository = InstanceFactory
					.getInstance(FiscalYearRepository.class);
		}
		return fiscalYearRepository;
	}

	public static void setFiscalYearRepository(
			FiscalYearRepository fiscalYearRepository) {
		FiscalYear.fiscalYearRepository = fiscalYearRepository;
	}

	public static MessageSourceAccessor getMessages() {
		return messages;
	}

	public static void setMessages(MessageSourceAccessor messages) {
		FiscalYear.messages = messages;
	}

	public Integer getYear() {
		return year;
	}

	public void setYear(Integer year) {
		this.year = year;
	}

	public Organization getOrg() {
		return org;
	}

	public void setOrg(Organization org) {
		this.org = org;
	}

	public Employee getOperator() {
		return operator;
	}

	public void setOperator(Employee operator) {
		this.operator = operator;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof FiscalYear == false) {
			return false;
		}
		if (this == obj) {
			return true;
		}
		FiscalYear rhs = (FiscalYear) obj;
		return new EqualsBuilder().append(getId(), rhs.getId()).isEquals();
	}

	@Override
	public int hashCode() {
		return new HashCodeBuilder(17, 37).append(getId()).toHashCode();
	}

	@Override
	public String toString() {
		return ToStringBuilder.reflectionToString(this,
				ToStringStyle.SHORT_PREFIX_STYLE);
	}

	/*
	 * =======================================
	 * 
	 * action
	 * 
	 * ========================================
	 */

	public void save() {
		validateYear();
		getFiscalYearRepository().save(this);
	}

	public void remove() {
		getFiscalYearRepository().remove(this);
	}

	public static FiscalYear get(Long id) {
		return getFiscalYearRepository().get(id);
	}

	public void validateYear() {
		Assert.notNull(year, messages.getMessage(
				"FiscalYear.validateYear.yearIsNull", "会计年度的年份不允许为空。"));
		Assert.notNull(org, messages.getMessage(
				"FiscalYear.validateYear.orgIsNull", "会计年度所属的机构不允许为空。"));

		if (isYearAlreadyExistInSameOrganization()) {
			throw new CompensationRuntimeException(messages.getMessage(
					"FiscalYear.validateYear.yearAlreadyExist", "该会计年度已经存在。"));
		}
	}

	public boolean isYearAlreadyExistInSameOrganization() {

		boolean isDuplicate = false;

		List<FiscalYear> years = findByOrganization(org);

		for (FiscalYear y : years) {

			isDuplicate = y.getYear().equals(year);

			if (isDuplicate) {

				if (!isNew() && getId().equals(y.getId())) {
					continue;
				} else {
					return isDuplicate;
				}

			}

		}

		return isDuplicate;

	}

	public static List<FiscalYear> findByOrganization(Organization org) {
		return getFiscalYearRepository().findByOrganization(org);
	}

}
